"""
基于epoll的并发服务模型
重点代码！
"""
from select import *
from socket import *

# 服务器地址
HOST = "0.0.0.0"
PORT = 8888
ADDR = (HOST,PORT)

# 创建监听套接字
sock = socket()
sock.bind(ADDR)
sock.listen(3)
# 配合非阻塞IO防止网络中断带来的内部阻塞
sock.setblocking(False)

# 创建epoll对象
ep = epoll()
# 设置查找字典 {fileno:sock}
map = {sock.fileno():sock}
ep.register(sock,EPOLLIN) # 设置关注

# 循环监控关注的IO发生
while True:
    events = ep.poll()  # [(fileno,event),(),]
    print("你有新的IO需要处理哦",events)
    # 循环查看哪个IO发生就处理哪个
    for fd,event in events:
        if fd == sock.fileno():
            # 处理客户端连接
            connfd, addr = map[fd].accept()
            print("Connect from", addr)
            connfd.setblocking(False)
            # 增加关注对象,设置边缘触发
            ep.register(connfd,EPOLLIN|EPOLLET)
            map[connfd.fileno()] = connfd # 维护字典
        elif event == EPOLLIN:
            # 处理客户端消息
            data = map[fd].recv(1024)
            # 处理客户端退出
            if not data:
                ep.unregister(fd) # 不再关注
                map[fd].close()
                del map[fd] # 从字典删除
                continue
            print(data.decode())
            # map[fd].send(b"Thanks")
            ep.unregister(fd) # 系统先清除
            ep.register(fd,EPOLLOUT)
        elif event == EPOLLOUT:
            map[fd].send(b"Thanks")
            ep.unregister(fd)
            ep.register(fd, EPOLLIN)


